#ifndef __TYPE_H
#define __TYPE_H 1
#include <stdint.h>
#include <stddef.h>
#include <common.h>
#include <vector>
#include <memory>
#include <unordered_map>

enum BuiltinType : int {
    kBuiltinVoid,
    kBuiltinBool,
    kBuiltinChar,
    kBuiltinShort,
    kBuiltinInt,
    kBuiltinLong,
    kBuiltinFloat,
    kBuiltinDouble,
};

struct TypeBuiltin {
private:
    BuiltinType _type;
    size_t _size;
    const char *_name;
    TypeBuiltin(BuiltinType type, size_t size, const char *name) : _type(type), _size(size), _name(name) {}
public:
    size_t size() const { return _size; }
    const char *name() const { return _name; }
    static TypeBuiltin Void;
    static TypeBuiltin Bool;
    static TypeBuiltin Char;
    static TypeBuiltin Short;
    static TypeBuiltin Int;
    static TypeBuiltin Long;
    static TypeBuiltin Float;
    static TypeBuiltin Double;
};

struct TypePointer {
    Type _base;
    size_t size() const { return 4;}
};

struct TypeArray {
    Type _base;
    size_t _dlen;
    size_t _size;
    TypeArray(Type base, size_t dlen);

    size_t size() const { return _size; }
};

struct TypeStruct {
    std::unordered_map<std::string, size_t> _offset;
    std::unordered_map<std::string, Type> _member;
    size_t _size;
    TypeStruct(std::vector<std::pair<Type, std::string>>& member);
    size_t size() const { return _size;};
};

size_t sizeType(Type);

size_t Align(size_t& length, Type type);

#endif // __TYPE_H
